package com.sky.blue.xmltool.betwixt;

import org.apache.commons.betwixt.io.BeanWriter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import org.xml.sax.InputSource;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;

/**
 * @author lzh
 * @date 2019/11/14 - 9:22
 */
public class BetwixtUtil {
    /**
     * xml的换行符
     */
    private static final String XML_ENDLINE = "\r\n";

    /**
     * betwixt文件路径
     */
    public static final String BETWIXTFILE_PATH = "betwixt/";

    /**
     * betwixt文件格式
     */
    private static final String BETWIXTFILT_FORMAT = ".betwixt";

    private static final String PRTTY_SPAN = "  ";

    /**
     * <将对象obj转成和输入流in格式相同的xml文件>
     *
     * @param in  输入流
     * @param obj 转换的对象
     * @return xml格式的字符串
     * @see [类、类#方法、类#成员]
     */
    private static String writeXml(InputStream in, Object obj, boolean endTag, boolean writeEmptyNode) {
        StringBuilder result = new StringBuilder();
        StringWriter stringWriter = new StringWriter();

        BeanWriter beanWriter = new BeanWriter(stringWriter);


        try {
            InputSource source = new InputSource(in);

            beanWriter.getXMLIntrospector().register(source);
            beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
            beanWriter.getBindingConfiguration().setMapIDs(false);
            beanWriter.writeXmlDeclaration("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

            beanWriter.setEndOfLine(XML_ENDLINE);
            beanWriter.setIndent(PRTTY_SPAN);
            beanWriter.setEndTagForEmptyElement(endTag);
            beanWriter.setWriteEmptyElements(writeEmptyNode);
            beanWriter.write(obj);
            result.append(stringWriter.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            IOUtilsExpand.closeQuietly(stringWriter);
            IOUtilsExpand.closeQuietly(beanWriter);
        }
        return result.toString();

    }

    // comes spring-core:PropertiesLoaderUtils.loadAllProperties
    private static InputStream loadFile(String fileName, boolean isWindows)
            throws IOException {
        if (isWindows) {
            return new FileInputStream(new File(fileName));
        }
        //spring获取类加载器
        ClassLoader loader = ClassUtils.getDefaultClassLoader();
        URL url = loader.getResource(fileName);
        URLConnection con = url.openConnection();
        //必要时使用缓存
        ResourceUtils.useCachesIfNecessary(con);
        return con.getInputStream();
    }



    /**
     * @param clazz          class
     * @param obj            对象
     * @param filePath       betwixt模板的路径（xml约束模板）
     * @param endTag         结束标记
     * @param writeEmptyNode 是否写空节点
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> String objToXml(Class<T> clazz, Object obj, String filePath, boolean endTag, boolean writeEmptyNode)
            throws IOException {
        String fileName = filePath + clazz.getSimpleName() + BETWIXTFILT_FORMAT;

        InputStream in = null;
        try {
            in = loadFile(fileName, false);
            return writeXml(in, obj, endTag, writeEmptyNode);
        } finally {
            IOUtilsExpand.closeQuietly(in);
        }




    }


    /**
     * @param clazz      class
     * @param obj        对象
     * @param writeEmpty 是否写空节点
     * @param <T>
     * @return
     * @throws Exception
     */
    public static <T> String objToXml(Class<T> clazz, Object obj, boolean writeEmpty)
            throws Exception {
        String loadFileName = BETWIXTFILE_PATH + clazz.getSimpleName() + BETWIXTFILT_FORMAT;
        InputStream in = null;
        try {
            in = loadFile(loadFileName, false);
            return writeXml(in, obj, true, writeEmpty);
        } finally {
            IOUtilsExpand.closeQuietly(in);
        }


    }




}
